package com.ttctracker.search;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Timer;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.ttctracker.R;
import com.ttctracker.classes.StopItem;
import com.ttctracker.util.SqlAdapter;
import com.ttctracker.xmlparser.SAXParserHelper;
import com.ttctracker.xmlparser.StopPredictionHandler;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Handler;
import android.text.Html;
import android.view.View.OnClickListener;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class SearchPredictionTask extends
		AsyncTask<String, Void, StopPredictionHandler> {

	private ProgressDialog progressDialog;
	private Context context;
	private HashMap<String, String> stopDetails;
	private StopItem resultStopItem;
	private String searchURL;
	private Dialog resultdDialog;
	private SAXParserHelper helper;
	private double elapsedTime;
	private Timer lastUpdatedTimer;
	private Handler lastUpdatedHandler;

	/**
	 * 
	 */
	public SearchPredictionTask(Context context) {
		this.context = context;
	}

	@Override
	protected void onPostExecute(StopPredictionHandler result) {

		progressDialog.dismiss();
		if (result != null) {
			stopDetails = result.getStopDetails();
			resultStopItem = result.getStopItem();
			lastUpdatedHandler = new Handler();
			resultdDialog = new Dialog(context);

			// Set dialog's content based on XML layout resource
			resultdDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
			resultdDialog.setContentView(R.layout.prediction_dialog_content);
			if (stopDetails != null && resultStopItem != null) {

				((TextView) resultdDialog
						.findViewById(R.id.prediction_dialog_route))
						.setText(stopDetails.get("routeTitle"));
				((TextView) resultdDialog
						.findViewById(R.id.prediction_dialog_direction))
						.setText(stopDetails.get("directionTitle"));

				String dialogBodyText = "";
				ArrayList<Integer> predictions = resultStopItem
						.get_prediction();

				dialogBodyText = getPredictionContent(predictions);
				((TextView) resultdDialog
						.findViewById(R.id.prediction_dialog_predictions))
						.setText(Html.fromHtml(dialogBodyText));

				// Set Dialog title with custom (scrolling) layout
				// to accommodate long text

				TextView dialogTitle = (TextView) resultdDialog
						.findViewById(R.id.dialog_title);
				dialogTitle.setText(resultStopItem.get_title());
				((Button) resultdDialog
						.findViewById(R.id.prediction_dialog_refresh))
						.setOnClickListener(refresh_prediction_listener());
				((Button) resultdDialog
						.findViewById(R.id.prediction_dialog_add))
						.setOnClickListener(add_stop_listener());
				
				resultdDialog.show();
				checkLastUpdated.run();

			}
		}else {
			AlertDialog.Builder builder = new AlertDialog.Builder(context);
			builder.setMessage("Sorry, unable to find stop details.\nPlease try again later.")
			       .setCancelable(false)
			       .setPositiveButton("Close", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			                dialog.dismiss();
			           }
			       });
			
			AlertDialog alert = builder.create();
			alert.show();
		}

	}

	private Runnable checkLastUpdated = new Runnable() {

		@Override
		public void run() {
			updateLastUpdated();
			lastUpdatedHandler.postDelayed(checkLastUpdated, 30000);
		}
	};

	private void updateLastUpdated() {
		((TextView) resultdDialog
				.findViewById(R.id.prediction_dialog_lastupdated))
				.setText("Last updated: " + Double.toString(elapsedTime)
						+ " minute(s) ago.");
		elapsedTime+=0.5;
	}

	private String getPredictionContent(ArrayList<Integer> predictions) {
		String dialogBodyText = "";
		int stopCounter = 1;
		for (Integer prediction : predictions) {
			if (stopCounter > 3) {
				break;
			} else {
				if (prediction >= 0) {

					String prediction_txt = Integer.toString(prediction);

					if (stopCounter == 1) {
						dialogBodyText += "<font color=\"red\"><b>";
						if (prediction != 0) {
							dialogBodyText += prediction_txt
									+ " Min</b></font><br/>";
						} else {
							dialogBodyText += "Due</b></font><br/>";
						}

					} else {
						dialogBodyText += "" + prediction_txt + " Min<br/>";
					}

				} else {
					dialogBodyText += "N/A";
					break;
				}
				stopCounter++;
			}

		}
		return dialogBodyText;
	}

	private OnClickListener add_stop_listener() {
		return new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				if (stopDetails != null && resultStopItem != null) {
					SqlAdapter adapter=new SqlAdapter(context);
					try {
						
						if (adapter.openDB()) {
							if (adapter.isOpen()) {
								long result=adapter.insertUserStop(resultStopItem);
								if (result==-1) {
									Toast.makeText(context, "Sorry, cannot add the stop.", Toast.LENGTH_SHORT).show();
								}else if(result==-99) {
									Toast.makeText(context, "You have added the stop already.", Toast.LENGTH_SHORT).show();
								}else {
									Toast.makeText(context, "Stop has been added successfully!!.", Toast.LENGTH_SHORT).show();
								}
							}
						}
						
					} catch (Exception e) {
						e.printStackTrace();
						Toast.makeText(context, "Sorry, cannot add the stop.", Toast.LENGTH_SHORT).show();
					}finally{
						if (adapter!=null &&adapter.isOpen()) {
							adapter.close();
						}
					}
				}

			}
		};
	}

	private OnClickListener refresh_prediction_listener() {
		return new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				if (stopDetails != null && resultStopItem != null) {

					Thread thread = new Thread(new Runnable() {

						@Override
						public void run() {

							TextView predictionText = (TextView) resultdDialog
									.findViewById(R.id.prediction_dialog_predictions);
							try {
								lastUpdatedHandler
										.removeCallbacks(checkLastUpdated);
								setupParserHelper(searchURL);
								helper.parseXml();
								StopItem stopItem = ((StopPredictionHandler) helper
										.getHandler()).getStopItem();
								predictionText.setText(Html
										.fromHtml(getPredictionContent(stopItem
												.get_prediction())));
								elapsedTime = 0;
								checkLastUpdated.run();
							} catch (Exception e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}

						}
					});

					thread.run();
					// new
					// RefreshPredictionTask(resultdDialog).execute(searchURL);
				}

			}
		};
	}

	@Override
	protected void onPreExecute() {
		progressDialog = new ProgressDialog(context);
		progressDialog.setMessage("Getting Stop prediction...");
		progressDialog.show();

	}

	private void setupParserHelper(String url) throws MalformedURLException,
			IOException, IllegalAccessException, InstantiationException,
			SAXException, ParserConfigurationException {
		searchURL = url;
		helper = new SAXParserHelper(new URL(searchURL).openStream(), StopPredictionHandler.class);
		helper.setup_parser();
		// helper.parseXml();
	}

	@Override
	protected StopPredictionHandler doInBackground(String... arg0) {
		// URL url=new URI(arg0[0]);

		try {
			setupParserHelper(arg0[0]);
			helper.parseXml();
			return ((StopPredictionHandler) helper.getHandler());

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

}
